import { DeleteOutlined, UploadOutlined } from '@ant-design/icons';
import { Button, Col, Form, message, Row, Upload } from 'antd';
import React, { useMemo, useRef } from 'react';

import CropIcon from '@/assets/svg/crop.svg';
import { LayerInfoFE } from '@/pages/TemplateEditor/interface';
import { DeepPartial } from '../../../../../../../../../interface';
import {
  MAX_IMAGE_HEIGHT,
  MAX_IMAGE_SIZE,
  MAX_IMAGE_WIDTH,
  MIN_IMAGE_EDGE
} from '../../constant';
import {
  createURLForFile,
  getImgDimension,
  ifUploadImageSortEdgeTooSmallAfterResize
} from '../../utils';
import styles from './index.module.less';

interface Props {
  loading: boolean;
  layer: LayerInfoFE;
  setLoading: (value: boolean) => void;
  onSetCropLayerId: (id: string) => void;
  onChange: (values: DeepPartial<LayerInfoFE>) => void;
}

const ImageConfigs = ({
  layer,
  loading,
  onChange,
  setLoading,
  onSetCropLayerId
}: Props): JSX.Element => {
  const data = layer.data.image || {};
  const uploaded = useMemo(() => !!data.name, [data.name]);
  const timerRef = useRef<{ timer?: number }>({});

  const uploadProps = {
    action: '/api/imagestop/design/upload',
    showUploadList: false,
    withCredentials: true,
    accept: '.jpg, .png, .jpeg',
    beforeUpload: async (file): Promise<boolean> => {
      if (file.size > MAX_IMAGE_SIZE) {
        message.error('Wrong image size, no larger than 10 MB.');
        return false;
      }

      const src = createURLForFile(file);
      const { width, height } = await getImgDimension(src);
      if (width * height > MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT) {
        message.error(
          `The uploaded image cannot exceed an area of ${MAX_IMAGE_WIDTH}x${MAX_IMAGE_HEIGHT} pixels.`
        );
        return false;
      }

      if (ifUploadImageSortEdgeTooSmallAfterResize(width, height)) {
        // sijia todo：临时文案
        message.error(
          `The uploaded image minimum edge can not smaller than ${MIN_IMAGE_EDGE} pixels after auto resize.`
        );
        return false;
      }

      setLoading(true);
      timerRef.current.timer = window.setTimeout(() => {
        message.loading({
          content: 'image uploading...',
          key: 'timer',
          duration: 0
        });
      });
    },
    customRequest: async (info): Promise<void> => {
      const { file } = info;
      const { name } = file;

      if (!file) {
        message.error('Upload fail.');
        setLoading(false);
        clearTimeout(timerRef.current.timer);
        return;
      }

      try {
        const formData = new FormData();
        formData.append('file', file);
        formData.append('image_type', 'cp_layer');
        const fileKey = Math.random();

        const src = createURLForFile(file);
        const { width, height } = await getImgDimension(src);

        message.success({ content: 'Upload success.', key: 'timer' });
        onChange({
          src,
          width,
          height,
          data: {
            image: {
              name,
              fileKey
            }
          }
        });
      } catch (error) {
        message.error({ content: 'Upload fail.', key: 'timer' });
      } finally {
        setLoading(false);
        clearTimeout(timerRef.current.timer);
      }
    }
  };

  const handleCrop = (): void => {
    onSetCropLayerId(layer.data.id);
  };

  const handleDelete = (): void => {
    onChange({
      src: '',
      width: 0,
      height: 0,
      data: {
        image: {
          name: ''
        }
      }
    });
  };

  return (
    <Row gutter={[24, 12]}>
      <Col span={24}>
        <Form.Item className={styles.container}>
          <div className={styles['upload-title']}>Image</div>
          {uploaded && (
            <div className={styles['uploaded-info']}>
              <div className={styles['uploaded-image']}>
                <img src={layer.src} alt="" />
              </div>
              <div className={styles['uploaded-image-name']} title={data.name}>
                {data.name}
              </div>
              <div className={styles['uploaded-image-btns']}>
                <Button
                  type="text"
                  disabled={!layer.src || loading}
                  onClick={handleCrop}
                  icon={<CropIcon />}
                />
                <Button
                  type="text"
                  disabled={!layer.src || loading}
                  onClick={handleDelete}
                  icon={<DeleteOutlined />}
                />
              </div>
            </div>
          )}
          <div style={{ display: uploaded ? 'none' : 'block' }}>
            <Upload {...uploadProps}>
              <Button icon={<UploadOutlined />} disabled={loading}>
                Upload
              </Button>
            </Upload>
          </div>
        </Form.Item>
      </Col>
    </Row>
  );
};

export default ImageConfigs;
